package ec.fugu.amf;

import java.io.IOException;
import java.util.Hashtable;

import net.rim.device.api.i18n.ResourceBundle; //Client tested in a BlackBerry SDK
import assets.res.XXXXResource; //Resorces for the BlackBerry 

import com.XXXX.views.XXXXBlackBerry; //View of the BlackBerry APP

import ec.fugu.util.ObserverInterface;

public class AmfClientThread extends Thread  implements XXXXResource{

    private static ResourceBundle _res = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);
    private ObserverInterface _ourObserver;
    private AmfClient _client = null;
    private String _method = null;
    private Object[] _params = null;
    private AmfMessage _response;
    private boolean _stopRequest = false;
    private boolean _needAuth = false;
    
    /**
     * Create a networkThread
     * @param client AmfClient to use in the Thread
     * @param method Remote method to be invoked
     * @param params Params of the Remote Method
     * @param timeout Timeout of the request
     * @param observer 
     */
    public AmfClientThread(AmfClient client, String method, Object[] params, ObserverInterface observer) {
        super();
        _client = client;
        _ourObserver = observer;
        _method = method;
        _params = params;
    }

    public AmfClientThread(AmfClient client, String method, Object[] params, ObserverInterface observer, boolean needAuth) {
        super();
        _client = client;
        _ourObserver = observer;
        _method = method;
        _params = params;
        _needAuth = needAuth;
    }

    /**
     * stop is called if the processing should not continue.
     */
    public void stop() {
        // Tell our observer
        observerError(ObserverInterface.CANCELLED, _res.getString(CANCELED));
        _stopRequest = true; // Will no longer tell Observer anything
        this.interrupt(); // Give our Thread a kick
    }

    private void observerStatusUpdate(final int status, final String statusString) {
        if ( !_stopRequest ) {
            _ourObserver.processStatusUpdate(status, statusString);
        }
    }

    private void observerError(int errorCode, String errorMessage) {
        if ( !_stopRequest ) {
            _ourObserver.processError(errorCode, errorMessage);
        }
    }

    private void observerResponse(AmfMessage reply) {
        if ( !_stopRequest ) {
            _ourObserver.processResponse(reply);
        }
    }

    /**
     * Process the long running or blocking operation in this Thread
     * Update the Observer as required using
     * - processStatus, whenever desired
     * and then one of:
     * - processError, if there was a problem
     * - processResponse, if the data was obtained OK
     */
    public void run () {
        boolean willFail = false; // false - will finshed OK, true - will fail!
//	        _startTime = System.currentTimeMillis();
//	        _finishTime = _startTime + _timeout;

        observerStatusUpdate(1, "Started"); // Tell user we have started
        try {
			_client.resetRequest();
      /*
       * XXXXBlackBerry.hasCredentials() returns a boolean,
       * true if the users has specified user and password
       * in the GUI of the BlackBerry APP, else false 
       */
			if(_needAuth && XXXXBlackBerry.hasCredentials()){
         //XXXXBlackBerry.getCredentials() returns a Hashtable with the credentials from the BlackBerry APP
    			Hashtable credentials = XXXXBlackBerry.getCredentials();
        		_client.setCredentials(credentials.get("username").toString(), credentials.get("password").toString());
			} else if(_needAuth && !XXXXBlackBerry.hasCredentials()){
				throw new IOException(_res.getString(MISSINGCREDENTIAL));
			}
			_client.sendRequest(_method, _params);
			_response=_client.getResponse();
	        observerStatusUpdate(100, "Finished"); // Tell Observer we have finished
		} catch (IOException e) {
			System.err.println("NetworkThread-run IOException: " + e.getMessage());
			e.printStackTrace();
			willFail = true;
		}
//	        _finishTime = System.currentTimeMillis();
        //  Did we finish OK or badly
        if ( willFail ) {
            observerError(ObserverInterface.ERROR, "Failed");
        } else {
            observerResponse(_response);
        }

        // Make sure we do nothing else
        _stopRequest = true;
        _ourObserver = null;
    }
}